package com.asamioffice.goldenport.servlet;

import java.io.*;
import java.util.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

/**
 * @since   Sep. 21, 2010
 * @version Apr. 11, 2011
 * @author  ASAMI, Tomoharu
 */
public class StubServletResponse implements HttpServletResponse {
    public List<Cookie> cookies = new ArrayList<Cookie>();
    public Map<String, String> headers = new LinkedHashMap<String, String>();
    public int status = SC_OK;
    public String errorMessage = null;
    public String encoding = null;
    public String contentType = null;
    public int contentLength = 0;
    public Locale locale = null;
    public ByteArrayOutputStream buffer = new ByteArrayOutputStream();

    ServletOutputStream out = new ServletOutputStream() {
        public void write(int c) {
            buffer.write(c);
        }
    };

    @Override
    public void addCookie(Cookie cookie) {
        cookies.add(cookie);
    }


    @Override
    public void setHeader(String name, String value) {
        headers.put(name, value);
    }

    @Override
    public void setIntHeader(String name, int value) {
        headers.put(name, Integer.toString(value));
    }

    @Override
    public void addHeader(String name, String value) {
        headers.put(name, value);
        if ("Content-Type".equals(name)) {
        	// TODO check out the HttpServletResponse of Tomcat and Jetty.
            contentType = value;
        }
    }

    @Override
    public void addIntHeader(String name, int value) {
        headers.put(name, Integer.toString(value));
    }

    @Override
    public void addDateHeader(String name, long value) {
        headers.put(name, "???" + value); // TODO
    }

    @Override
    public boolean containsHeader(String name) {
        return headers.containsKey(name);
    }

    @Override
    public String encodeRedirectURL(String name) {
        throw new UnsupportedOperationException();
    }

    @Override
    public String encodeRedirectUrl(String name) {
        throw new UnsupportedOperationException();
    }

    @Override
    public String encodeURL(String name) {
        throw new UnsupportedOperationException();
    }

    @Override
    public String encodeUrl(String name) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void sendError(int status) throws IOException {
        this.status = status;
    }

    @Override
    public void sendError(int status, String message) throws IOException {
        this.status = status;
        this.errorMessage = message;
    }

    @Override
    public void sendRedirect(String name) throws IOException {
        throw new UnsupportedOperationException();
    }

    @Override
    public void setDateHeader(String name, long value) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void setStatus(int status) {
        this.status = status;
    }

    @Override
    public void setStatus(int status, String message) {
        this.status = status;
        this.errorMessage = message;
    }

    @Override
    public void flushBuffer() throws IOException {
    }

    @Override
    public int getBufferSize() {
        return buffer.size();
    }

    @Override
    public ServletOutputStream getOutputStream() throws IOException {
        return out;
    }

    @Override
    public PrintWriter getWriter() throws IOException {
        return new PrintWriter(out);
    }

    @Override
    public boolean isCommitted() {
        throw new UnsupportedOperationException();
    }

    @Override
    public void reset() {
        throw new UnsupportedOperationException();
    }

    @Override
    public void resetBuffer() {
        throw new UnsupportedOperationException();
    }

    @Override
    public void setBufferSize(int arg0) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void setCharacterEncoding(String encoding) {
        this.encoding = encoding;
    }

    @Override
    public String getCharacterEncoding() {
        return encoding;
    }

    @Override
    public void setContentLength(int length) {
        this.contentLength = length;
    }

    @Override
    public void setContentType(String contenttype) {
        this.contentType = contenttype;
    }

    @Override
    public String getContentType() {
        return contentType;
    }

    @Override
    public void setLocale(Locale locale) {
        this.locale = locale;
    }

    @Override
    public Locale getLocale() {
        return locale;
    }

    public String getTextContent() {
        String enc;
        if (encoding != null) enc = encoding;
        else enc = "utf-8";
        try {
            return new String(buffer.toByteArray(), enc);
        } catch (UnsupportedEncodingException e) {
            throw new InternalError(e.getMessage());
        }
    }

    public byte[] getBinaryContent() {
        return buffer.toByteArray();
    }

    public Object getContent() {
        if (_is_text_content()) {
            return getTextContent();
        } else if (buffer.size() > 0) {
            return getBinaryContent();
        } else {
            return getBinaryContent(); //"";
        }
    }

    private boolean _is_text_content() {
        if (contentType != null) {
            if (contentType.startsWith("text/")) return true;
            if (contentType.startsWith("application/xml")) return true;
            return false;
        } else if (encoding != null) {
            return true;
        } else {
            return false;
        }
    }
}
